// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-11-9

#ifndef __SVR_SERVER_H_COMMON_SVR_BASE__
#define __SVR_SERVER_H_COMMON_SVR_BASE__

#pragma once

#include "base_timer.h"
#include "db_source.h"
#include "db_sourceset.h"
#include "db_command.h"
#include "svr_servertype.h"
#include "svr_pingecho.h"
#include <common/base/utility.h>

class CJoyServerWnd;

namespace JoyServer
{

class CJoyUser;
class CJoyUserSet;
class CJoyUserPool;
class CJoyShowInfo;
class CJoyServerConfig;
class CJoyAsyncExec;
class CJoyAsyncObject;
class CJoyReleaseUser;
class CJoyDbMsgHandler;
class CJoyMsgWnd;

// timing taskes.
class CJoyTmUserActive;
class CJoyTmUpdateServer;
class CJoyTmPopWindow;

class CJoyClientVersion
{
public:
    UINT    m_mainVer;
    UINT    m_fileVer;
};

class CJoyServer
{
protected:
    virtual bool InitDatabase();
    virtual void FreeDatabase();
    virtual bool InitUserSets();
    virtual void FreeUserSets();
    virtual bool InitTimingTask();
    virtual void FreeTimingTask();

    virtual bool InsertOnlineServer();
    virtual void RemoveOnlineServer();

public:
    typedef CArray<CJoyUserSet*> CUserSets;
    typedef CMap<CString, const CString&, DWORD, DWORD> CTimingMap;

    CJoyMsgWnd* m_mainThreadWnd;
    CJoyServerWnd*  m_serverWnd;

    // ping replay.
    CJoyPingEchoSocket  m_pingEcho;

    // thread pool
    CJoyAsyncExec*  m_asyncExec;

    // pools for loginned user.
    CJoyCriticalSection m_userSetsLock;
    CUserSets       m_userSets;

    // temp pool for connected user.
    CJoyUserPool*   m_userPool;

    CJoyReleaseUser*m_releaseUser;

    CJoyShowInfo*       m_showInfo;
    CJoyServerConfig*   m_serverConfig;

    // timing tasks.
    CJoyTimer   m_timer;
    CJoyTmUserActive*   m_tmUserActive;
    CJoyTmUpdateServer* m_tmUpdateServer;
    CTimingMap  m_defaultTiming;
    CTimingMap  m_serverTiming;
    UINT        m_timingGroup;

    // use to process messages to database.
    CJoyDbMsgHandler*   m_dbMsgHandler;

    // server attributes
    CString     m_serverName;
    CString     m_serverIP;
    UINT        m_serverPort;
    UINT        m_serverId;
    UINT        m_serverType;
    UINT        m_serverRegion;
    UINT        m_clientId;
    UINT        m_clientMainVer;
    UINT        m_clientFileVer;
    UINT        m_userDbId;
    CJoyCriticalSection         m_versionLock;
    CArray<CJoyClientVersion>   m_clientVersions;
    CJoyAtomCount   m_versionChange;
    bool m_started;
    bool m_stopping;

    CJoyAtomCount   m_userCount_All;
    CJoyAtomCount   m_userCount_Normal;
    UINT            m_userCount_Max;

    // data sources
    CJoyDbSource    m_dbServer;     // server configuration db.
    CJoyDbSource    m_dbUser;       // readonly user database.
    CJoyDbSource    m_dbUserSave;   // unique user database to save user informations.

    CJoyOServDbSourceSet    m_dbSetOServ;
    CJoyOUserDbSourceSet    m_dbSetOUser;
public:
    CJoyServer();
    virtual ~CJoyServer();

    virtual bool Create();
    virtual void Destroy();

    virtual CJoyServerConfig*   AllocConfig() = 0;
    virtual CJoyReleaseUser*    AllocReleaseUser();
    virtual CJoyUser*           AllocUser();
    virtual CJoyUserSet*        AllocUserSet();
    virtual CJoyUserPool*       AllocUserPool();
    virtual CJoyAsyncExec*      AllocAsyncExec();
    virtual CJoyTmUserActive*   AllocTmUserActive();
    virtual CJoyTmUpdateServer* AllocTmUpdateServer();
	
    virtual CJoyDbMsgHandler*   AllocDbMsgHandler();

    void SetShowInfo(CJoyShowInfo* showInfo);
    CJoyShowInfo* GetShowInfo()
    {
        return m_showInfo;
    }
    void QueueAsyncObject(CJoyAsyncObject* pObj);
    void QueueReleaseUser(CJoyUser* pUser);

    bool CheckVersion(const CJoyClientVersion& v);
    virtual void LoadClientVersions(CJoyDbCommand& rsAttrib);

    CJoyDbSource& GetOnlineDbSource()
    {
        return m_dbSetOServ.GetSource(m_serverId);
    }

    bool FindTiming(const CString& strName, DWORD& dwValue);

	virtual bool UpdateUserSets(UINT *roomIds, UINT *roomCount); //*-----------------------------------------------------updateNewRoom

};

} // namespace JoyServer

#endif  // __SVR_SERVER_H_COMMON_SVR_BASE__